﻿#region document_info

// /*
//  ************************************************
//  * 当前解决方案: 
//  * 当前模块名称: 
//  * 当前文件名称: TcpHeartbeat.cs
//  * 文档作者姓名: 
//  * 文档创建时间: 2022-02-22 11:32
//  * 最后修改时间: 2022-02-22 11:32
//  * 文档内容来源:
//  * 代码用途简介:
//  * 代码调用说明:
//  ************************************************
//  */

#endregion

#region USING

using System;
using System.Text;
using System.Threading.Tasks;
using TouchSocket.Core;
using TouchSocket.Sockets;

#endregion

namespace TestTouchSocket;

public class TcpHeartbeat : IDisposable
{
    private readonly TcpClient tcpClient;

    private TcpHeartbeat()
    {
        tcpClient ??= new TcpClient();

        tcpClient.Connected += OnConnected;
        tcpClient.Closed += OnClosed;
        tcpClient.Received += OnReceived;

        //声明配置
        var config = new TouchSocketConfig();
        config.SetRemoteIPHost(new IPHost("127.0.0.1:19722"));
        config.ConfigurePlugins(p => { p.UseTcpReconnection().UsePolling(TimeSpan.FromSeconds(5)); });

        //载入配置
        tcpClient.Setup(config);

        StartConnectByTask().ConfigureAwait(false);

        SendHeartbeatByTask().ConfigureAwait(false);
    }

    private async Task StartConnectByTask()
    {
        var online = tcpClient?.Online ?? false;
        while (!online)
        {
            try
            {
                await tcpClient?.ConnectAsync()!;
            }
            catch (Exception e)
            {
                Console.WriteLine($"!!!=== HeartBeat=>连接异常.{e.Message}");
            }
            finally
            {
                online = tcpClient?.Online ?? false;
            }

            await Task.Delay(15 * 1000);
        }
    }

    private Task OnReceived(ITcpClient client, ReceivedDataEventArgs args)
    {
        var bytes = args.ByteBlock?.ToArray();

        //客户端接收信息
        if (bytes == null || bytes?.Length <= 0)
        {
            return Task.CompletedTask;
        }

        var msg = Encoding.UTF8.GetString(bytes, 0, bytes.Length);
        Console.WriteLine($"!!!=== HeartBeat=>接收到消息:{msg}");
        return Task.CompletedTask;
    }

    private Task OnClosed(ITcpClient client, ClosedEventArgs e)
    {
        //从服务器断开连接，当连接不成功时不会触发
        Console.WriteLine($"!!!=== HeartBeat=>已断开连接.{e?.Message}");

        return Task.CompletedTask;
    }

    private Task OnConnected(ITcpClient client, ConnectedEventArgs e)
    {
        //成功连接到服务器
        Console.WriteLine("!!!=== HeartBeat=>已成功连接.");

        return Task.CompletedTask;
    }

    private async Task SendHeartbeatByTask()
    {
        while (true)
        {
            SendHeartBeat();
            await Task.Delay(5 * 1000);
        }
    }

    private void SendHeartBeat()
    {
        if (tcpClient?.Online != true)
        {
            return;
        }

        var buffer = Encoding.UTF8.GetBytes("---heartbeat---");
        if (buffer is { Length: > 0 })
        {
            tcpClient?.Send(buffer);

            Console.WriteLine($"!!!=== HeartBeat=>发送心跳...包长={buffer.Length}");
        }
    }

    private void Cleanup()
    {
        if (tcpClient != null)
        {
            tcpClient.Connected -= OnConnected;
            tcpClient.Closed -= OnClosed;
            tcpClient.Received -= OnReceived;

            tcpClient?.TryShutdown();
            tcpClient?.Close();
            tcpClient?.Dispose();
        }

        if (lazy?.IsValueCreated == true)
        {
            lazy = null;
        }
    }

    #region 初始化

    private static Lazy<TcpHeartbeat> lazy = new(() => new TcpHeartbeat());

    public static TcpHeartbeat Instance => lazy.Value;

    public void Dispose()
    {
        Cleanup();
    }

    #endregion
}